﻿using BCCommon;
using BCData.MySql.BusinessFlowInstance;
using BCData.MySql.BusinessFlowStepInstance;
using BCData.OA.BusinessFlowCategory;
using BCData.OA.BusinessFlowModel.BusinessFlowModel;
using BCData.OA.BusinessFlowModel.BusinessFlowStepModel;
using BCData.Sim.Company.Company;
using BCDto.OA.BusinessFlowModel.BusinessFlowModel;
using BCEntity.OA.BusinessFlowModel.BusinessFlowModel;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BCService.OA.BusinessFlowModel.BusinessFlowModel
{
    public class BusinessFlowModelService : IBusinessFlowModelService
    {
        private readonly IApplicationContextService applicationContextService;
        private readonly IBusinessFlowModelData businessFlowModelData;
        private readonly ICompanyData companyData;
        private readonly IBusinessFlowStepModelData businessFlowStepModelData;
        private readonly IBusinessFlowInstanceData businessFlowInstanceData;
        private readonly IBusinessFlowStepInstanceData businessFlowStepInstanceData;
        private readonly IBusinessFlowCategoryData businessFlowCategoryData;
        public BusinessFlowModelService(IApplicationContextService applicationContextService,
            IBusinessFlowModelData businessFlowModelData, 
            ICompanyData companyData,
            IBusinessFlowStepModelData businessFlowStepModelData,
            IBusinessFlowInstanceData businessFlowInstanceData,
            IBusinessFlowStepInstanceData businessFlowStepInstanceData,
            IBusinessFlowCategoryData businessFlowCategoryData)
        {
            this.applicationContextService = applicationContextService;
            this.businessFlowModelData = businessFlowModelData;
            this.companyData = companyData;
            this.businessFlowStepModelData = businessFlowStepModelData;
            this.businessFlowInstanceData = businessFlowInstanceData;
            this.businessFlowStepInstanceData = businessFlowStepInstanceData;
            this.businessFlowCategoryData = businessFlowCategoryData;
        }

        public bool Exists(long businessFlowModelId)
        {
            return this.businessFlowModelData.Exists(businessFlowModelId).GetAwaiter().GetResult();
        }

        public bool Exists(string businessFlowModelCode)
        {
            return this.businessFlowModelData.Exists(businessFlowModelCode).GetAwaiter().GetResult();
        }

        public BusinessFlowModelDto Add(BusinessFlowModelRequestDto requestDto)
        {
            if (this.businessFlowModelData.Exists(requestDto.BusinessFlowModelCode).GetAwaiter().GetResult())
            {
                throw new ArgumentException("业务流模型编码已存在");
            }
            var entity = requestDto.As<BusinessFlowModelEntity>();
            //if (applicationContextService.Admin.IsHeadOffice)
            //{
            //    var companyEntity = this.companyData.GetEntity(requestDto.CompanyId).GetAwaiter().GetResult();
            //    if (companyEntity == null)
            //    {
            //        throw new ArgumentException("此公司不存在");
            //    }
            //    entity.CompanyName = companyEntity.CompanyName;
            //}
            //else
            //{
                entity.CompanyId = applicationContextService.Admin.CompanyId;
                entity.CompanyName = applicationContextService.Admin.CompanyName;
            //}
            var categoryEntity = this.businessFlowCategoryData.GetEntity(requestDto.BusinessFlowCategoryId).GetAwaiter().GetResult();
            if (categoryEntity == null)
            {
                throw new ArgumentException("此业务流分类不存在");
            }
            if (categoryEntity.CompanyId != applicationContextService.Admin.CompanyId)
            {
                throw new ArgumentException("请选择本公司的业务流分类");
            }
            entity.BusinessFlowCategoryId = categoryEntity.BusinessFlowCategoryId;
            entity.BusinessFlowCategoryName = categoryEntity.BusinessFlowCategoryName;
            entity.TotalStep = 0;
            entity.CurrentlyStep = 0;
            return this.businessFlowModelData.Add(entity).GetAwaiter().GetResult().As<BusinessFlowModelDto>();
        }

        public BusinessFlowModelDto Update(BusinessFlowModelPutDto putDto)
        {
            if (!this.Exists(putDto.BusinessFlowModelId))
            {
                throw new ArgumentException("此记录不存在");
            }
            var oldEntity = this.businessFlowModelData.GetEntity(putDto.BusinessFlowModelId).GetAwaiter().GetResult();
            if (oldEntity.BusinessFlowModelName != putDto.BusinessFlowModelName)
            {
                if (this.businessFlowModelData.Exists(putDto.BusinessFlowModelCode).GetAwaiter().GetResult())
                {
                    throw new ArgumentException("业务流模型编码已存在");
                }
            }
            var entity = putDto.As<BusinessFlowModelEntity>();
            //if (applicationContextService.Admin.IsHeadOffice)
            //{
            //    var companyEntity = this.companyData.GetEntity(putDto.CompanyId).GetAwaiter().GetResult();
            //    if (companyEntity == null)
            //    {
            //        throw new ArgumentException("此公司不存在");
            //    }
            //    entity.CompanyName = companyEntity.CompanyName;
            //}
            //else
            //{
                entity.CompanyId = applicationContextService.Admin.CompanyId;
                entity.CompanyName = applicationContextService.Admin.CompanyName;
            //}
            var modelList = this.businessFlowStepModelData.GetList(entity.BusinessFlowModelId).GetAwaiter().GetResult();
            var categoryEntity = this.businessFlowCategoryData.GetEntity(putDto.BusinessFlowCategoryId).GetAwaiter().GetResult();
            if (categoryEntity == null)
            {
                throw new ArgumentException("此业务流分类不存在");
            }
            if (categoryEntity.CompanyId != applicationContextService.Admin.CompanyId)
            {
                throw new ArgumentException("请选择本公司的业务流分类");
            }
            entity.BusinessFlowCategoryId = categoryEntity.BusinessFlowCategoryId;
            entity.BusinessFlowCategoryName = categoryEntity.BusinessFlowCategoryName;
            entity.TotalStep = modelList.Count();
            entity.CurrentlyStep = 0;
            return this.businessFlowModelData.Update(entity).GetAwaiter().GetResult().As<BusinessFlowModelDto>();
        }

        public bool Delete(long businessFlowModelId)
        {
            if (!this.Exists(businessFlowModelId))
            {
                throw new ArgumentException("此记录不存在");
            }
            if (this.businessFlowStepModelData.InUsed(businessFlowModelId).GetAwaiter().GetResult())
            {
                throw new ArgumentException("此记录已被使用，无法删除");
            }
            else
            {
                if (this.businessFlowInstanceData.InUsed(businessFlowModelId).GetAwaiter().GetResult())
                {
                    throw new ArgumentException("此记录已被使用，无法删除");
                }
            }
            return this.businessFlowModelData.Delete(businessFlowModelId).GetAwaiter().GetResult();
        }

        public BusinessFlowModelDto GetEntity(long businessFlowModelId)
        {
            return this.businessFlowModelData.GetEntity(businessFlowModelId).GetAwaiter().GetResult().As<BusinessFlowModelDto>();
        }

        public BusinessFlowModelDto GetEntity(string businessFlowModelCode)
        {
            return this.businessFlowModelData.GetEntity(businessFlowModelCode).GetAwaiter().GetResult().As<BusinessFlowModelDto>();
        }

        public IEnumerable<BusinessFlowModelDto> GetList(int companyId)
        {
            return this.businessFlowModelData.GetList(companyId).GetAwaiter().GetResult().As<IEnumerable<BusinessFlowModelDto>>();
        }

        public PageableList<BusinessFlowModelDto> Query(int companyId, string businessFlowModelName, DateTime? start, DateTime? end, int pageIndex, int pageSize)
        {
            var (list, count) = this.businessFlowModelData.Query(companyId, businessFlowModelName, start, end, pageIndex, pageSize).GetAwaiter().GetResult();

            return new PageableList<BusinessFlowModelDto>
            {
                Items = list.As<IEnumerable<BusinessFlowModelDto>>(),
                Count = count,
                PageIndex = pageIndex,
                PageSize = pageSize
            };
        }

    }
}
